package com.chaosj.skill.guava

import com.google.common.collect.Lists
import com.google.common.hash.BloomFilter
import com.google.common.hash.Funnel
import com.google.common.hash.Funnels
import com.google.common.hash.PrimitiveSink
import lombok.Data

import java.lang.invoke.MethodHandleImpl
import java.nio.charset.Charset

/**
 * @Description:
 * @author: caoyangjie
 * @date: 2019年11月2019/11/18日 13:41
 * @Copyright: © 赢时胜
 */
class GuavaBloomFilter {
    private static int size = 1000000
    private static BloomFilter<FilterEntity> bloomFilter = BloomFilter.create(new Funnel<FilterEntity>() {
        @Override
        void funnel(FilterEntity from, PrimitiveSink into) {
            into.putBoolean(from.exist)
            into.putString(from.name, Charset.forName("UTF-8"))
            into.putInt(from.value)
        }
    }, size,0.0001)

    static void main(String[] args){
        for (int i = 0; i < size; i++) {
            bloomFilter.put(new FilterEntity("name"+i,i,i%2==0))
        }

        for (int i = 0; i < size; i++) {
            if( !bloomFilter.mightContain(new FilterEntity("name"+i,i,i%2==0)) ){
                System.out.println(String.format("%s 数字逃逸了,请注意!",i))
            }
        }

        List<Integer> accidents = Lists.newArrayListWithCapacity(size)
        for (int i = size; i < size*2; i++) {
            if( bloomFilter.mightContain(new FilterEntity("name"+i,i,i%2==0)) ){
                accidents.add(i)
            }
        }

        System.out.println(String.format("%s 个数字被误伤了",accidents.size()))
    }

    @Data
    static class FilterEntity{
        String name
        int value
        boolean exist

        FilterEntity(String name, int value, boolean exist) {
            this.name = name
            this.value = value
            this.exist = exist
        }
    }
}
